package com.senni.config;

import com.alibaba.fastjson.JSON;
import feign.InvocationHandlerFactory;
import feign.Target;
import feign.Util;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Map;

public class FeginInvocationHandler implements InvocationHandler {
    private final Target target;
    private final Map<Method, InvocationHandlerFactory.MethodHandler> dispatch;

    FeginInvocationHandler(Target target,Map<Method, InvocationHandlerFactory.MethodHandler> dispatch){
        this.target = (Target) Util.checkNotNull(target, "target", new Object[0]);
        this.dispatch = (Map)Util.checkNotNull(dispatch, "dispatch for %s", new Object[]{target});
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (!"equals".equals(method.getName())) {
            if ("hashCode".equals(method.getName())) {
                return this.hashCode();
            } else if("toString".equals(method.getName())){
                return  this.toString();
            }else{
                InvocationHandlerFactory.MethodHandler methodHandler = this.dispatch.get(method);

                if(args==null||args.length==0){
                    return methodHandler.invoke(args);
                }
                Object[] newParam=new Object[args.length];
                Parameter[] parameters = method.getParameters();
                for (int i = 0; i < parameters.length; i++) {
                    Parameter parameter = parameters[i];
                    RequestBody annotation = parameter.getAnnotation(RequestBody.class);
                    if(annotation!=null){
                        String s = JSON.toJSONString(args[i]);
                        newParam[i]=s;
                    }else{
                        newParam[i]=args[i];
                    }
                }
                return  methodHandler.invoke(newParam);
            }
        } else {
            try {
                Object otherHandler = args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
                return this.equals(otherHandler);
            } catch (IllegalArgumentException var5) {
                return false;
            }
        }
    }
}
